"""
老黄历和万年历API模块
@Author: Converted from PHP to Python
@Date: 2025-07-26
@Description: 提供老黄历查询和万年历功能
"""

from fastapi import APIRouter, HTTPException
from pydantic import BaseModel
from typing import Optional, Dict, Any
import requests
import json
import mysql.connector
from datetime import datetime, date
import os
from ..core.config import settings

router = APIRouter()

# 数据模型
class CalendarResponse(BaseModel):
    """老黄历响应模型"""
    status: str
    message: str
    data: Optional[Dict[Any, Any]] = None

class CalendarData(BaseModel):
    """日历数据模型"""
    date: str
    result: Dict[Any, Any]
    day: Optional[Dict[Any, Any]] = None

class SolarTermsData(BaseModel):
    """节气数据模型"""
    name: str
    time: str
    date: str
    year: str

class CalendarService:
    """日历服务类"""
    
    def __init__(self):
        # API密钥从环境变量获取
        self.api_key = settings.juhe_api_key or "84bcbea372bdafa26884fdfa53b26963"  # 提供默认值作为备用
        
        # 数据库配置
        self.db_config = {
            'host': settings.db_host,
            'user': settings.db_user,
            'password': settings.db_password,
            'database': settings.db_database,
            'charset': 'utf8mb4'
        }
    
    def get_database_connection(self):
        """获取数据库连接"""
        try:
            return mysql.connector.connect(**self.db_config)
        except mysql.connector.Error as e:
            raise HTTPException(status_code=500, detail=f"数据库连接失败: {str(e)}")
    
    def juhe_http_request(self, url: str, params: str, is_post: bool = False) -> Optional[str]:
        """
        聚合数据HTTP请求方法
        """
        try:
            headers = {
                'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2272.118 Safari/537.36'
            }
            
            if is_post:
                response = requests.post(url, data=params, headers=headers, timeout=12)
            else:
                response = requests.get(f"{url}?{params}", headers=headers, timeout=12)
            
            if response.status_code == 200:
                return response.text
            else:
                return None
                
        except requests.RequestException as e:
            print(f"请求异常: {str(e)}")
            return None
    
    def get_laohuangli_data(self, query_date: str) -> Dict[Any, Any]:
        """
        获取老黄历数据
        """
        conn = self.get_database_connection()
        cursor = conn.cursor(dictionary=True)
        
        try:
            # 先查询数据库是否有当天的数据
            cursor.execute(
                "SELECT result, day FROM calendar WHERE dt LIKE %s",
                (f"{query_date}%",)
            )
            existing_data = cursor.fetchone()
            
            if existing_data:
                return json.loads(existing_data['result'])
            
            # 如果数据库没有数据，则调用API
            api_url = 'http://v.juhe.cn/laohuangli/d'
            params = {
                'key': self.api_key,
                'date': query_date
            }
            params_string = '&'.join([f"{k}={v}" for k, v in params.items()])
            
            response = self.juhe_http_request(api_url, params_string, True)
            
            if not response:
                raise HTTPException(status_code=500, detail="API请求失败")
            
            result = json.loads(response)
            
            if result.get('error_code') != 0:
                raise HTTPException(
                    status_code=500, 
                    detail=f"API错误: {result.get('error_code')}_{result.get('reason')}"
                )
            
            # 保存到数据库
            current_datetime = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
            insert_data = {
                'dt': current_datetime,
                'date': query_date,
                'result': json.dumps(result['result'], ensure_ascii=False)
            }
            
            cursor.execute(
                "INSERT INTO calendar (dt, date, result) VALUES (%(dt)s, %(date)s, %(result)s)",
                insert_data
            )
            
            # 获取万年历数据
            self.get_calendar_day_data(query_date, cursor)
            
            conn.commit()
            return result['result']
            
        except Exception as e:
            conn.rollback()
            raise HTTPException(status_code=500, detail=f"获取老黄历数据失败: {str(e)}")
        finally:
            cursor.close()
            conn.close()
    
    def get_calendar_day_data(self, query_date: str, cursor=None):
        """
        获取万年历数据
        """
        should_close = False
        if cursor is None:
            conn = self.get_database_connection()
            cursor = conn.cursor(dictionary=True)
            should_close = True
        
        try:
            # 检查是否已有记录
            cursor.execute("SELECT id FROM calendar WHERE date = %s", (query_date,))
            existing_record = cursor.fetchone()
            
            if existing_record:
                # 转换日期格式 Y-n-j (如: 2025-7-26)
                date_obj = datetime.strptime(query_date, "%Y-%m-%d")
                formatted_date = f"{date_obj.year}-{date_obj.month}-{date_obj.day}"
                
                api_url = 'http://v.juhe.cn/calendar/day'
                params = {
                    'key': self.api_key,
                    'date': formatted_date
                }
                params_string = '&'.join([f"{k}={v}" for k, v in params.items()])
                
                response = self.juhe_http_request(api_url, params_string, True)
                
                if response:
                    result = json.loads(response)
                    if result.get('error_code') == 0:
                        day_data = json.dumps(result['result']['data'], ensure_ascii=False)
                        cursor.execute(
                            "UPDATE calendar SET day = %s WHERE date = %s",
                            (day_data, query_date)
                        )
                        if should_close:
                            conn.commit()
        
        except Exception as e:
            if should_close:
                conn.rollback()
            print(f"获取万年历数据失败: {str(e)}")
        finally:
            if should_close:
                cursor.close()
                conn.close()
    
    def update_solar_terms(self):
        """
        更新节气数据
        """
        conn = self.get_database_connection()
        cursor = conn.cursor(dictionary=True)
        
        try:
            cursor.execute("SELECT result FROM solarterms")
            solar_terms_data = cursor.fetchall()
            
            for row in solar_terms_data:
                data = json.loads(row['result'])
                if data and len(data) > 0:
                    term_info = data[0]
                    name = term_info['name']
                    
                    update_data = {
                        'time': term_info['pub_time'],
                        'date': term_info['pri_date'],
                        'year': '2021'
                    }
                    
                    cursor.execute(
                        "UPDATE solarterms SET time = %(time)s, date = %(date)s, year = %(year)s WHERE name = %(name)s",
                        {**update_data, 'name': name}
                    )
            
            conn.commit()
            return {"status": "success", "message": "节气数据更新成功"}
            
        except Exception as e:
            conn.rollback()
            raise HTTPException(status_code=500, detail=f"更新节气数据失败: {str(e)}")
        finally:
            cursor.close()
            conn.close()

# 创建服务实例
calendar_service = CalendarService()

# API路由定义
@router.get("/api/calendar", response_model=CalendarResponse)
async def get_calendar():
    """
    获取当天老黄历信息
    """
    try:
        today = date.today().strftime("%Y-%m-%d")
        calendar_data = calendar_service.get_laohuangli_data(today)
        
        return CalendarResponse(
            status="success",
            message="获取老黄历数据成功",
            data=calendar_data
        )
    
    except HTTPException:
        raise
    except Exception as e:
        raise HTTPException(status_code=500, detail=f"获取老黄历失败: {str(e)}")

@router.get("/api/calendar/{query_date}", response_model=CalendarResponse)
async def get_calendar_by_date(query_date: str):
    """
    获取指定日期的老黄历信息
    参数: query_date - 日期格式 YYYY-MM-DD
    """
    try:
        # 验证日期格式
        datetime.strptime(query_date, "%Y-%m-%d")
        
        calendar_data = calendar_service.get_laohuangli_data(query_date)
        
        return CalendarResponse(
            status="success",
            message=f"获取{query_date}老黄历数据成功",
            data=calendar_data
        )
    
    except ValueError:
        raise HTTPException(status_code=400, detail="日期格式错误，请使用YYYY-MM-DD格式")
    except HTTPException:
        raise
    except Exception as e:
        raise HTTPException(status_code=500, detail=f"获取老黄历失败: {str(e)}")

@router.post("/api/calendar/solar-terms/update")
async def update_solar_terms():
    """
    更新节气数据
    """
    try:
        result = calendar_service.update_solar_terms()
        return CalendarResponse(
            status="success",
            message="节气数据更新成功",
            data=result
        )
    
    except HTTPException:
        raise
    except Exception as e:
        raise HTTPException(status_code=500, detail=f"更新节气数据失败: {str(e)}")

@router.get("/api/calendar/test")
async def test_calendar():
    """
    测试老黄历API
    """
    try:
        today = date.today().strftime("%Y-%m-%d")
        
        conn = calendar_service.get_database_connection()
        cursor = conn.cursor(dictionary=True)
        
        cursor.execute(
            "SELECT result FROM calendar WHERE dt LIKE %s",
            (f"{today}%",)
        )
        result = cursor.fetchall()
        
        cursor.close()
        conn.close()
        
        return CalendarResponse(
            status="success",
            message="测试成功",
            data={
                "calendar_data": result,
                "current_date": today,
                "endpoints": [
                    "GET /api/calendar - 获取今日老黄历",
                    "GET /api/calendar/{date} - 获取指定日期老黄历",
                    "POST /api/calendar/solar-terms/update - 更新节气数据"
                ]
            }
        )
    
    except Exception as e:
        raise HTTPException(status_code=500, detail=f"测试失败: {str(e)}")
